package main

import (
	"encoding/binary"
	"log"
	"math"
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

func initHttpRoutes() {
	router.Use(func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
		c.Writer.Header().Set("Access-Control-Max-Age", "86400")
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")

		if c.Request.Method == "OPTIONS" {
			c.AbortWithStatus(200)
			return
		}

		c.Next()
	})
	router.POST("/api/variable/setting", setting)
	// router.POST("/api/variable/threshold/modify", thresholdModify)
	router.GET("/api/error/get", getErrors)
	router.GET("/api/error/get_all_station", getErrors)
}

func setting(c *gin.Context) {
	type OptStruct struct {
		Name     string
		Value    float32
		Is_pulse bool
		Pt       int
	}
	var obj OptStruct
	if err := c.ShouldBindJSON(&obj); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}
	var fitPt *PtStruct = nil
	for _, item := range ptArray {
		if item.Name == obj.Name {
			fitPt = &item
			break
		}
	}
	if fitPt != nil {
		if fitPt.Type == "BOOL" {
			start := fitPt.Hold * 2
			boolArray := [16]byte{}
			for i := 0; i < 8; i++ {
				boolArray[i] = (modbusResults[start+1] & (1 << i))
				boolArray[i+8] = (modbusResults[start] & (1 << i))
			}
			boolArray[fitPt.BoolIndex] = byte(obj.Value)
			var byte1, byte2 byte
			for i := 0; i < 8; i++ {
				if boolArray[i] != 0 {
					byte1 |= 1 << i
				}
				if boolArray[i+8] != 0 {
					byte2 |= 1 << i
				}
			}
			modbusClient.WriteMultipleRegisters(uint16(fitPt.Hold), 1, []byte{byte2, byte1})
			if obj.Is_pulse {
				duration := time.Duration(obj.Pt) * time.Millisecond
				time.AfterFunc(duration, func() {
					boolArray[int(fitPt.BoolIndex)] = byte(0)
					for i := 0; i < 8; i++ {
						if boolArray[i] != 0 {
							byte1 |= 1 << i
						}
						if boolArray[i+8] != 0 {
							byte2 |= 1 << i
						}
					}
					modbusClient.WriteMultipleRegisters(uint16(fitPt.Hold), 1, []byte{byte2, byte1})
				})
			}
		}
		if fitPt.Type == "WORD" {
			curData := make([]byte, 2)
			value := uint16(obj.Value)
			binary.LittleEndian.PutUint16(curData[:2], value)
			curData[0], curData[1] = curData[1], curData[0]
			_, err := modbusClient.WriteMultipleRegisters(uint16(fitPt.Hold), 1, curData)
			if err != nil {
				log.Fatal(err)
			}
		}
		if fitPt.Type == "FLOAT" {
			curData := make([]byte, 4)
			binary.LittleEndian.PutUint32(curData, math.Float32bits(obj.Value))
			curData[0], curData[1], curData[2], curData[3] = curData[1], curData[0], curData[3], curData[2]
			_, err := modbusClient.WriteMultipleRegisters(uint16(fitPt.Hold), 2, curData)
			if err != nil {
				log.Fatal(err)
			}
		}
	}
	c.JSON(http.StatusOK, gin.H{"code": 200, "message": "success"})
}

func getErrors(c *gin.Context) {

	pageNumberStr := c.DefaultQuery("page_number", "1") // 设置默认页码为 1
	pageSizeStr := c.DefaultQuery("page_size", "20")    // 设置默认页面大小为 10

	pageNumber, _ := strconv.Atoi(pageNumberStr)
	pageSize, _ := strconv.Atoi(pageSizeStr)

	offset := pageSize * (pageNumber - 1)
	dbModel := myDB.Model(&ErrorStruct{}).Order("trigger_time DESC")
	var total int64 = 0
	dbModel.Count(&total)
	// 计算总页数
	totalPages := int((total + int64(pageSize) - 1) / int64(pageSize)) // 向上取整
	var list []ErrorStruct
	dbModel.Limit(pageSize).Offset(offset).Find(&list)

	c.JSON(http.StatusOK, map[string]interface{}{
		"code": 200,
		"data": map[string]interface{}{
			"errors":    list,
			"total":     total,
			"pageCount": totalPages,
		},
	})
}
